from dash import Dash, html, dcc


def test_xss001_banned_protocols(dash_duo):
    app = Dash()

    app.layout = html.Div(
        [
            dcc.Link("dcc-link", href="javascript:alert(1)", id="dcc-link"),
            html.Br(),
            html.A(
                "html.A",
                href='javascr\n\nipt:alert(1);console.log("xss");',
                id="html-A",
            ),
            html.A(
                "html.A.escape",
                id="html-A-escape",
                href="""javascript\x09\x0a:alert(1)""",
            ),
            html.A(
                "html.A.encoded",
                id="html-A-encoded",
                href="&#0000106&#0000097&#0000118&#0000097&#0000115&#0000099&#0000114&#0000105&#0000112&#0000116&#0000058&#0000097&#0000108&#0000101&#0000114&#0000116&#0000040&#0000039&#0000088&#0000083&#0000083&#0000039&#0000041",
            ),
            html.Br(),
            html.Form(
                [
                    html.Button(
                        "form-action",
                        formAction="javascript:alert('form-action')",
                        id="button-form-action",
                    ),
                    html.Button("submit", role="submit"),
                ],
                action='javascript:alert(1);console.log("xss");',
                id="form",
            ),
            html.Iframe(src='javascript:alert("iframe")', id="iframe-src"),
            html.ObjectEl(data='javascript:alert("data-object")', id="object-data"),
            html.Embed(src='javascript:alert("embed")', id="embed-src"),
        ]
    )

    dash_duo.start_server(app)

    for element_id, prop in (
        ("#dcc-link", "href"),
        ("#html-A", "href"),
        ("#html-A-escape", "href"),
        ("#html-A-encoded", "href"),
        ("#iframe-src", "src"),
        ("#object-data", "data"),
        ("#embed-src", "src"),
        ("#button-form-action", "formAction"),
    ):

        element = dash_duo.find_element(element_id)
        prop_value = element.get_attribute(prop)
        assert (
            prop_value == "about:blank"
        ), f"Failed prop: {element_id}.{prop} = {prop_value}"


def test_xss002_blank_href(dash_duo):
    app = Dash()

    app.layout = html.Div(dcc.Link("dcc-link", href="", id="dcc-link-no-href"))

    dash_duo.start_server(app)

    element = dash_duo.find_element("#dcc-link-no-href")
    assert element.get_attribute("href") is None

    assert dash_duo.get_logs() == []


def test_xss003_data_allowed(dash_duo):
    app = Dash()

    app.layout = html.Div(
        [
            html.Img(
                id="image",
                src="",
            )
        ]
    )

    dash_duo.start_server(app)
    element = dash_duo.find_element("#image")
    assert element.get_attribute("src") != "about:blank"
    assert dash_duo.get_logs() == []
